#ifndef _TD_TURRET_MANAGER_H_ 
#define _TD_TURRET_MANAGER_H_ 

/************************************************************************/
/* STL                                                                  */
/************************************************************************/
#include <map>
#include <set>

/************************************************************************/
/* Core                                                                 */
/************************************************************************/
#include "Core/Manager.h"
#include "Core/Utils.h"

/************************************************************************/
/* Game                                                                 */
/************************************************************************/
#include "Game/Factories/TowerFactory.h"
#include "Game/Game Objects/Towers/BaseTower.h"
#include "Game/Game Objects/Marios/BaseMario.h"
#include "Game/Tilemaps/TurretTilemap.h"


using namespace std;
using namespace TD_Core;
using namespace TD_Resources;

namespace TD_Game {
	
	class TowerManager : public Manager<BaseTower> {
		

		//If the towers must be updated
		bool m_updateTowers;

		//The turretTilemap, responsible for turret rendering
		TurretTilemap *m_pTurretTilemap;

		//Tileset of the turrets
		const Tileset * m_pTileset;

		//Tileset of the shots
		const Tileset * m_pShotTileset;

		//Singleton static variable
		static TowerManager * m_pTowerManager;
		
		set<unsigned int> m_renderQueue;

		map<unsigned int , BaseTower *> m_sellMap;
		
		/************************************************************************/
		/* ctors and dtors                                                      */
		/************************************************************************/
	
		//Default constructor
		explicit TowerManager();

		//Copy constructor
		explicit TowerManager(const TowerManager &rhs);

		//Assignment constructor
		TowerManager & operator=(const TowerManager &rhs);

		
	public:

		/************************************************************************/
		/* Singleton                                                            */
		/************************************************************************/
		static TowerManager * getInstance();

		/************************************************************************/
		/* Access functions                                                     */
		/************************************************************************/
		void setTileset(const Tileset *g_pTileset) {
			m_pTileset = g_pTileset;
		} 
		
		const Tileset * getTileset() const {
			return(m_pTileset);
		}

		TurretTilemap * getTilemap() const {
			return(m_pTurretTilemap);
		}
		void setShotTileset(const Tileset *g_pTileset) {
			m_pShotTileset = g_pTileset;
		}

		BaseTower * getTower(unsigned int towerID) const {
			return(static_cast<BaseTower *>(getObject(towerID)));
		}
	

		/************************************************************************/
		/* Functionalities                                                      */
		/************************************************************************/
		bool loadTilemap(const Tileset *g_pTileset, const string &tileMapStr, const Coord2D & mapPosition, const Coord2D &numTiles);
		
		void createTower(const Coord2D &towerPos, towerTypes towerType = ancientTower);

		void sellTower(unsigned int towerID);

	

		void render(SDL_Surface *const g_destSurface, unsigned int deltaTime);
		void update(int deltaTime);

		bool hasTower(const Coord2D &towerPos) const {
			unsigned int towerID = towerPos.x + (towerPos.y * 1000);
			if(getObject(towerID)) 
				return true;
			return false;
		}

		void clear();

		inline void updateTowers(bool update) {
			m_updateTowers = update;
		}



	};

}

#endif